package com.bingxue.edu.management.auth.controller;

import com.bingxue.edu.common.enums.SocialAccountEnum;
import com.bingxue.edu.framework.common.constant.CacheConstants;
import com.bingxue.edu.framework.common.model.Response;
import com.bingxue.edu.framework.common.util.ValidationUtils;
import com.bingxue.edu.framework.redis.RedisUtils;
import com.bingxue.edu.framework.security.justauth.AuthRequestFactory;
import com.bingxue.edu.management.auth.EmployeeAuthUtil;
import com.bingxue.edu.management.auth.model.AuthEmployee;
import com.bingxue.edu.management.auth.model.req.UserBasicInfoUpdateReq;
import com.bingxue.edu.management.auth.model.req.UserPasswordUpdateReq;
import com.bingxue.edu.management.auth.model.req.UserPhoneUpdateReq;
import com.bingxue.edu.management.auth.model.resp.AvatarResp;
import com.bingxue.edu.management.auth.model.resp.EmployeeUserSocialBindResp;
import com.bingxue.edu.management.auth.service.EmployeeUserCenterService;
import com.bingxue.edu.management.auth.service.SocialAccountService;
import com.bingxue.edu.management.system.model.entity.SocialAccount;
import com.bingxue.edu.management.system.service.EmployeeService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.constraints.NotNull;
import lombok.RequiredArgsConstructor;
import me.zhyd.oauth.model.AuthCallback;
import me.zhyd.oauth.model.AuthResponse;
import me.zhyd.oauth.model.AuthUser;
import me.zhyd.oauth.request.AuthRequest;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.List;

import static com.bingxue.edu.management.auth.EmployeeAuthUtil.STP;

/**
 * 登录认证控制器
 * @author panbo
 * @since 2024/6/28
 */
@Tag(name = "个人中心接口")
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class EmployeeUserCenterController {
    private final EmployeeUserCenterService employeeUserCenterService;
    private final SocialAccountService socialAccountService;
    private final AuthRequestFactory authRequestFactory;
    private final EmployeeService employeeService;

    @Operation(summary = "获取用户信息", description = "获取登录用户信息")
    @GetMapping("/info")
    public Response<AuthEmployee> getUserInfo() {
        AuthEmployee authEmployee = EmployeeAuthUtil.getAuthUser();
        return Response.success(authEmployee);
    }

    // Todo:未完成
    @Operation(summary = "修改头像", description = "用户修改个人头像")
    @PostMapping("/avatar")
    public Response<AvatarResp> updateAvatar(@NotNull(message = "头像不能为空") MultipartFile avatarFile) throws IOException {
//        ValidationUtils.throwIf(avatarFile::isEmpty, "头像不能为空");
//        String newAvatar = employeeUserCenterService.updateAvatar(avatarFile, EmployeeAuthUtil.getCurrentUserId());
//        AvatarResp resp = AvatarResp.builder().avatar(newAvatar).build();
//        return Response.success(resp);
        return null;
    }

    @Operation(summary = "修改基础信息", description = "修改用户基础信息")
    @PatchMapping("/update-basic-info")
    public Response<Void> updateBasicInfo(@Validated @RequestBody UserBasicInfoUpdateReq req) {
        employeeUserCenterService.updateBasicInfo(req, EmployeeAuthUtil.getCurrentUserId());
        //更新session
        AuthEmployee authEmployee = EmployeeAuthUtil.getAuthUser();
        authEmployee.getUserInfo().setName(req.getName());
        authEmployee.getUserInfo().setGender(req.getGender());
        STP.getTokenSession().set(CacheConstants.LOGIN_USER_KEY, authEmployee);
        return Response.success();
    }

    @Operation(summary = "修改密码", description = "修改用户登录密码")
    @PatchMapping("/update-password")
    public Response<Void> updatePassword(@Validated @RequestBody UserPasswordUpdateReq updateReq) {
        employeeUserCenterService.updatePassword(updateReq.getOldPassword(),updateReq.getNewPassword(), EmployeeAuthUtil.getCurrentUserId());
        return Response.success();
    }

    @Operation(summary = "修改手机号", description = "修改手机号")
    @PatchMapping("/update-phone")
    public Response<Void> updatePhone(@Validated @RequestBody UserPhoneUpdateReq updateReq) {
        String captchaKey = CacheConstants.CAPTCHA_KEY_PREFIX + updateReq.getPhone();
        String captcha = RedisUtils.get(captchaKey);
        ValidationUtils.throwIfBlank(captcha, "验证码已失效");
        ValidationUtils.throwIfNotEqualIgnoreCase(updateReq.getCaptcha(), captcha, "验证码错误");
        RedisUtils.delete(captchaKey);
        employeeUserCenterService.updatePhone(updateReq.getPhone(), updateReq.getOldPassword(), EmployeeAuthUtil.getCurrentUserId());
        AuthEmployee authEmployee = EmployeeAuthUtil.getAuthUser();
        authEmployee.getUserInfo().setMobilePhone(updateReq.getPhone());
        STP.getTokenSession().set(CacheConstants.LOGIN_USER_KEY, authEmployee);
        return Response.success();
    }


    @Operation(summary = "查询绑定的三方账号", description = "查询绑定的三方账号")
    @GetMapping("/social-list")
    public Response<List<EmployeeUserSocialBindResp>> listSocialBind() {
        List<SocialAccount> socialAccountList = socialAccountService.listByUserId(EmployeeAuthUtil.getCurrentUserId());
        List<EmployeeUserSocialBindResp> employeeSocialBindList = socialAccountList.stream().map(socialAccount -> {
            String source = socialAccount.getSource();
            EmployeeUserSocialBindResp userSocialBind = new EmployeeUserSocialBindResp();
            userSocialBind.setSource(source);
            userSocialBind.setDescription(SocialAccountEnum.valueOf(source).getLabel());
            return userSocialBind;
        }).toList();
        return Response.success(employeeSocialBindList);
    }

    @Operation(summary = "绑定三方账号", description = "绑定三方账号")
    @Parameter(name = "source", description = "来源", example = "WECHAT_OPEN", in = ParameterIn.PATH)
    @PostMapping("/social-bind/{source}")
    public Response<Void> bindSocial(@PathVariable String source, @RequestBody AuthCallback callback) {
        AuthRequest authRequest = authRequestFactory.get(source);
        AuthResponse<AuthUser> response = authRequest.login(callback);
        ValidationUtils.throwIf(!response.ok(), response.getMsg());
        AuthUser authUser = response.getData();
        socialAccountService.bind(authUser, EmployeeAuthUtil.getCurrentUserId());
        return Response.success();
    }

    @Operation(summary = "解绑三方账号", description = "解绑三方账号")
    @Parameter(name = "source", description = "来源", example = "WECHAT_OPEN", in = ParameterIn.PATH)
    @DeleteMapping("/social-unbind/{source}")
    public Response<Void> unbindSocial(@PathVariable String source) {
        socialAccountService.deleteBySourceAndUserId(source, EmployeeAuthUtil.getCurrentUserId());
        return Response.success();
    }
}
